#include "test_thread_pool.h"

/*==============================<线程池类>==============================*/
ThreadPool::ThreadPool(size_t num_threads) : stop(false)
{
     for (size_t i = 0; i < num_threads; ++i)
    {
        // 将lambda函数作为线程的入口点
        this->workers.emplace_back([this]
        {
            while (true)
            {
                Task* task = nullptr;

                {
                    std::unique_lock<std::mutex> lock(this->queue_mutex);
                    
                    this->condition.wait(lock, [this]
                    {
                        return !this->tasks.empty() || this->stop;//任务队列不空，或线程池停止才能唤醒（防止伪唤醒）
                    });//wait阻塞的时候会自动释放锁，唤醒的时候会重新获取锁，不会死锁

                    // 如果线程池停止且任务队列为空，则当前工作线程退出循环
                    if (this->stop && this->tasks.empty())
                    {
                        return;
                    }

                    // 从任务队列中取出任务
                    task = this->tasks.front();
                    this->tasks.pop();
                }

                if (task)
                {
                    task->execute(); // 执行任务
                    delete task;     // 任务执行完毕后，释放内存
                }
            }
        });
    }
    std::cout << "ThreadPool initialized with " << num_threads << " threads." << std::endl; 
}

ThreadPool::~ThreadPool()
{
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        stop = true; // 设置停止标记
    }
    condition.notify_all(); // 通知所有等待的线程退出

    // 等待所有工作线程完成
    for (std::thread& worker : workers)
    {
        if (worker.joinable())//检查线程对象是否可以被join或detach
        {
            worker.join(); // 阻塞当前线程，直到worker线程执行完毕
        }
    }
    std::cout << "ThreadPool destroyed." << std::endl;
}

void ThreadPool::enqueue(Task* task)
{
    {
        std::unique_lock<std::mutex> lock(queue_mutex);
        if (stop)
        {
            // 如果线程池已经停止，不允许再提交任务
            std::cerr << "Warning: Cannot enqueue task, thread pool is stopped." << std::endl;
            delete task; // 避免内存泄漏
            return;
        }
        tasks.push(task); // 将任务加入队列
    }
    condition.notify_one(); // 通知一个等待的线程有新任务
}
